package fibonacci

import "fmt"

func FibRescuvie (x uint) uint64 {
	if x > 93 { return 0 }  // uint64最多可以存第93个数，再高就溢出了
	switch x {
	case 0:
		return 0
	case 1, 2:
		return 1
	default:
		return FibRescuvie(x-2) + FibRescuvie(x-1)
	}
}

var cache = map[uint]uint64{0: 0, 1: 1, 2: 1}

func FibRescuvieCache (x uint) uint64 {
	if x > 93 { return 0 }
	if _, ok := cache[x]; ok {
		return cache[x]
	}
	cache[x] = FibRescuvieCache(x-2) + FibRescuvieCache(x-1)
	fmt.Println(x, cache[x])
	return cache[x]
}


func FibTailRescuvie (first, second uint64, n uint, result chan <- uint64) {
	if n > 93 { result <- 0 }
	if n <=2 {
		result <- 1
	} else if n == 3 {
		result <- first + second
	}
	go FibTailRescuvie(second, first+second, n-1, result)
}


func FibForLoop (x uint) uint64 {
	first := uint64(1)
	second := uint64(1)
	var r uint64
	for i := uint(3); i <= x; i++ {
		r = first + second
		first, second = second, r
	}
	return r
}